package com.mew.common.util;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;


/**
 * @Author petrel
 * @Date 2020/11/13 0013
 **/
public class NumberUtil extends cn.hutool.core.util.NumberUtil {

    public static boolean isLtOne(Number number){
        return null== number || number.longValue() < 1 ? true : false;
    }

    public static boolean isLtZero(Number number){
        return null== number || number.longValue() < 0 ? true : false;
    }

    public static boolean isNull(Number number){
        return null== number ? true : false;
    }

    public static boolean isUnZero(Number number){
        return null == number || number.longValue() == 0 ? true : false;
    }

    public static boolean isMustRangeInt(int val, int range1, int range2){
        if (range2 == -1){
            return val >= range1;
        }
        if (range1 > range2){
            return  val > range1 ? false : range2 <= val && val < range1;
        }else {
            return   val > range2 ? false : range1 <= val && val < range2;
        }
    }

    public static double randomDoubleByStr(String str, CharSequence separator, int scale){
        String[] strs = StrUtil.split(str, separator);
        return RandomUtil.randomDouble(Double.parseDouble(strs[0]), Double.parseDouble(strs[1]), scale, RoundingMode.UP);
    }


    public static int randomIntByStr(String str, CharSequence separator){
        int[] ints = StrUtil.splitToInt(str, separator);
        return RandomUtil.randomInt(ints[0], ints[1]+1);
    }
    public static long randomLongByStr(String str, CharSequence separator){
        long[] longs = StrUtil.splitToLong(str, separator);
        return RandomUtil.randomLong(longs[0], longs[1]+1);
    }

    public static long getGoldNumberByWan(int wan){
        return  wan * 10000;
    }

    public static long getGoldByKilo(int kilo){
        return  kilo  * 1000;
    }

    public static double division(long v1, long v2){
        return  new BigDecimal(String.valueOf(v1))
                .divide( new BigDecimal(String.valueOf(v2)), 2, BigDecimal.ROUND_DOWN ).doubleValue();
    }

    //1 表示进入，0表示不进入
    public static int proOneIn(int pro){
        if (pro >=100){
            return 1;
        }
        if (pro <= 0 ){
            return 0;
        }

        int random = RandomUtil.randomInt(1, 100);
        return random <= pro ? 1 : 0;
    }


    public static int proMultiStr(String str){
        if (StringUtils.isEmpty(str)){
            return  -1;
        }
        String[] arg = str.split("-");

        int[] arry = new int[arg.length];
        for (int i=0; i<arg.length; i++){
            arry[i] = Integer.parseInt(arg[i]);
        }

        return proMultiIn(arry);
    }

    /**
     * 多个值
     * @param pros
     * @return 如果返回 0表示不进入， 返回 1表示概率命中 pros 第1个， 返回 2表示概率命中 pros 第2个，
     */
    public static int proMultiIn(int[] pros){
        if (pros.length == 1){
            return proOneIn(pros[0]);
        }
        int random = RandomUtil.randomInt(1, 100);
        int temp = 0;
        int addTemp = 0;
        for (int i=0; i< pros.length; i++){
            addTemp += pros[i];
            if (isMustRangeInt(random, temp, addTemp)){
                return i+1;
            }
            temp += pros[i];
        }
        return 0;
    }

    /**
     * str能否转int
     * @param str
     * @return
     */
    public static boolean canParseInt(String str){
        if(StringUtils.isEmpty(str)){ //验证是否为空
            return false;
        }

        return str.matches("\\d+"); //使用正则表达式判断该字符串是否为数字，第一个\是转义符，\d+表示匹配1个或 //多个连续数字，"+"和"*"类似，"*"表示0个或多个

    }

    public static int proportion(Number numerator , Number denominator, int scn){
        if (NumberUtil.isLtOne(numerator)  || NumberUtil.isLtOne(denominator) ){
            return 0;
        }
        double da = new BigDecimal(String.valueOf(numerator))
                .divide( new BigDecimal(String.valueOf(denominator)), 3, BigDecimal.ROUND_DOWN).doubleValue();
        return (int)(da * scn);
    }


    /**
     * 指定数值和几率配置,随机获取数值
     * 例如roundnums{0,1,2,3}  probabilitys{45,30,15,10}
     *     出      0:45%    1:30%    2:15%     3:10%
     * @param roundnums 数值数组
     * @param probabilitys 几率数组
     * @return  随机数值
     * @throws Exception 配置数组大小必须一样,几率配置和必须是100
     * @author tsl
     */
    public static int produceRateRandomNumber(int[] roundnums,int[] probabilitys){
        if(roundnums.length!=probabilitys.length){
            throw new IllegalArgumentException("数值和概率设置不匹配");
        }
        int sumprobabilitys=0;
        for(int probability:probabilitys){
            sumprobabilitys+=probability;
        }
        if(sumprobabilitys!=100){
            throw new IllegalArgumentException("百分比之和必须为100%");
        }
        int randnum=RandomUtil.randomInt(0,100);
        int percentScopeMin=0;
        int percentScopeMax=0;
        for(int idx=0;idx<probabilitys.length;idx++){
            percentScopeMin=percentScopeMax;
            percentScopeMax+=probabilitys[idx];
            if(randnum>=percentScopeMin&&randnum<percentScopeMax){
                return roundnums[idx];
            }
        }
        return -1;
    }


    public static int randInt(int start, int end, int... exclude){
        return randCry(start, end, 0, exclude);
    }

    private static int randCry(int start, int end, int size, int... exclude){
        int temp = RandomUtils.nextInt(start, end+1);
        if (!Arrays.stream(exclude).anyMatch(x -> x == temp)){
            return temp;
        }
        if (size > 50){
            return start;
        }
        return randCry(start, end, ++size, exclude);
    }


    public static int mapSize(int size){
        return (int) (size/0.75+1);
    }

    public static BigDecimal randomBigDecimalByStr(String str, CharSequence separator){
        String[] ints = StrUtil.split(str, separator);
        if (ints[0].equals(ints[1])){
            return new BigDecimal(ints[0]);
        }
        return RandomUtil.randomBigDecimal(new BigDecimal(ints[0]), new BigDecimal(ints[1])).setScale(2,BigDecimal.ROUND_DOWN);
    }

}
